module GYLite{
    export class GraphicsElement extends BatchElement{   
        /**实际原图开始颜色*/public startColor:number;
        /**实际原图结束颜色*/public endColor:number;             
        /**颜色数组，大于1个颜色则为渐变*/public $color:number[];
        /**透明度数组*/public $alpha:number[];
        /**渐变比例*/public $ratio:number[];        
        /**端点宽度*/public $capWidth:number;
        /**间隙*/public $gap:number;
        /**2倍间隙*/public $gap2:number;
        /**X轴半径*/public $radiusX:number;
        /**Y轴半径*/public $radiusY:number;
        /**原点X*/public $originX:number;
        /**原点Y*/public $originY:number;
        
        /**中间拉伸部分X的尺寸*/public $scaleSizeX:number;
        /**中间拉伸部分Y的尺寸*/public $scaleSizeY:number;
        /**圆角半径X*/public $rectRadiusX:number;
        /**圆角半径Y*/public $rectRadiusY:number;
        /**边缘模糊像素*/public $blurSize:number;
        /**线条9切片*/public $lineRect:GYLite.Scale9GridRect;
        /**细线条9切片*/public $lineTinyRect:GYLite.Scale9GridRect;
        /**边距*/public $padding:number;
        /**矢量类型*/public $type:GraphicsType;
        /**渐变类型*/public $gradientType:string;
        /**渐变矩阵*/public $gradientMatrix:egret.Matrix;
        /**矢量线段拐角类型 "bevel" | "miter" | "round"*/
        public lineJoin:CanvasLineJoin;		
		/**笔触宽度*/
        public lineWidth:number;		
		/**线段端点的类型 "butt" | "round" | "square"*/
        public lineCap:CanvasLineCap;		
        /**全局透明度*/public $globalAlpha:number;        
        public constructor(){
            super();
        }
        public reset(param:any,type:GraphicsType=null):void
        {
            let s= this;
            let color:number[]=null,alpha:number[]=null,lineWidth:number,lineCap:CanvasLineCap=null;
            let scaleSizeX:number,scaleSizeY:number;
            let blurSizeX:number,blurSizeY:number;
            
            color = param.color?param.color:[0xffffff];
            alpha = param.alpha;
            s.$gradientType = param.gradientType?param.gradientType:null;
            s.$gradientMatrix = param.gradientMatrix?param.gradientMatrix:null;
            
            lineWidth = param.lineWidth?param.lineWidth:1;
            lineCap = param.lineCap?param.lineCap:"round";            
            s.$blurSize = param.blurSize?param.blurSize:0;
            s.$radiusX = param.radiusX?param.radiusX:0;
            s.$radiusY = param.radiusY?param.radiusY:0;
            s.$ratio = param.ratio?param.ratio:null;
            scaleSizeX = param.scaleSizeX?param.scaleSizeX:NaN;
            scaleSizeY = param.scaleSizeY?param.scaleSizeY:NaN;
            s.lineWidth = lineWidth;
            s.lineCap = lineCap;  
            s.$type = type;
            blurSizeX = s.blurSizeX;
            blurSizeY = s.blurSizeY;  
            if(type == GraphicsType.POINT)
            {
                s.$gap = 1;
                s.$gap2 = s.$gap*2;            
                s.$padding = 0;
                s.$scaleSizeX = s.$scaleSizeY = 0;
                s.$capWidth = (lineWidth == 1 || lineCap == "butt")?0:lineWidth;
                s.width = s.$scaleSizeX + s.$gap2 + s.$capWidth * 2;
                s.height = s.$scaleSizeY + lineWidth + s.$gap2;                            
                s.$originX = s.$gap + s.$capWidth;
                s.$originY = s.$gap + (lineWidth == 1?0:lineWidth / 2);
            }
            else if(type == GraphicsType.LINE)
            {   
                s.$gap = 1;
                s.$gap2 = s.$gap*2;            
                s.$capWidth = (lineWidth == 1 || lineCap == "butt")?0:lineWidth;
                s.$padding = 0;                
                s.lineCap = lineCap;
                s.$scaleSizeX = scaleSizeX == scaleSizeX?scaleSizeX:2;
                s.$scaleSizeY = scaleSizeY == scaleSizeY?scaleSizeY:0;
                s.width = s.$scaleSizeX + s.$gap2 + blurSizeX * 2;
                s.height = s.$scaleSizeY + lineWidth + s.$gap2 + blurSizeY * 2;
                s.$originX = s.$gap + blurSizeX;
                s.$originY = s.$gap + blurSizeY;
                s.$lineRect = new GYLite.Scale9GridRect(1,1,1,1);
                s.$lineRect.topGap = s.$lineRect.bottomGap = s.$originY - blurSizeY + 0.024*s.height;//笔触纵向的九宫格则只排除gap即可                
                s.$lineRect.leftGap = s.$lineRect.rightGap = s.$originX - blurSizeX + (s.$gradientType || blurSizeX > 0?0:(s.$scaleSizeX-1)/2) + 0.024*s.width;//笔触横向的九宫格只保留1像素
            }
            else if(type == GraphicsType.RECT || type == GraphicsType.TRIANGLE)
            {
                s.$gap = 1;
                s.$gap2 = s.$gap*2;
                s.$capWidth = s.$padding = 0;
                s.lineWidth = lineWidth;
                s.lineCap = lineCap;
                s.$scaleSizeX = scaleSizeX == scaleSizeX?scaleSizeX:5;
                s.$scaleSizeY = scaleSizeY == scaleSizeY?scaleSizeY:5;
                s.width = s.$scaleSizeX + s.$gap2 + s.$blurSize * 2;
                s.height = s.$scaleSizeY + s.$gap2 + s.$blurSize * 2;
                s.$originX = s.$gap + s.$blurSize;
                s.$originY = s.$gap + s.$blurSize;
                s.$lineRect = new GYLite.Scale9GridRect(2,2,2,2);
                s.$lineRect.topGap = s.$lineRect.bottomGap = s.$originY - s.$blurSize;
                s.$lineRect.leftGap = s.$lineRect.rightGap = s.$originX - s.$blurSize;
            }
            else if(type == GraphicsType.ROUNDRECT)
            {
                s.$gap = 1;
                s.$gap2 = s.$gap*2;            
                s.$capWidth = s.$padding = 0;                
                s.lineWidth = lineWidth;
                s.lineCap = lineCap;                                
                s.$originX = s.$gap;
                s.$originY = s.$gap;
                s.$lineRect = new GYLite.Scale9GridRect(2,2,2,2);                
                s.setRoundRectRadius(param.radiusX,param.radiusY);
            }
            else if(type == GraphicsType.CIRCLE || type == GraphicsType.ELLIPSE)
            {
                s.$gap = 1;
                s.$gap2 = s.$gap*2;            
                s.$capWidth = s.$padding = 0;
                s.lineWidth = lineWidth;
                s.lineCap = lineCap;
                s.$scaleSizeX = s.$radiusX*2;
                s.$scaleSizeY = s.$radiusY*2;
                s.width = s.$scaleSizeX + s.$gap2 + s.$blurSize * 2;
                s.height = s.$scaleSizeY + s.$gap2 + s.$blurSize * 2;
                s.$originX = s.$gap + s.$blurSize;
                s.$originY = s.$gap + s.$blurSize;
                s.$lineRect = new GYLite.Scale9GridRect(2,2,2,2);
                // s.$lineRect.topGap = s.$lineRect.bottomGap = s.$originY - s.$blurSize;//笔触纵向的九宫格则只排除gap即可
                // s.$lineRect.leftGap = s.$lineRect.rightGap = s.$originX + (s.$scaleSizeX-1)/2;//笔触横向的九宫格只保留1像素
            }            
            if(alpha)
            {
                if(alpha.length <= 1)
                    s.$globalAlpha = alpha[0]?alpha[0]:0;
                else
                    s.$globalAlpha = 1;
            }
            else
                s.$globalAlpha = 1;            
            s.$color = color;
            s.$alpha = alpha;
        }
        public get globalAlpha():number
        {
            return this.$globalAlpha;
        }
        /**填充的颜色、渐变或模式*/
        public getFillStyle(ctx:CanvasRenderingContext2D):string | CanvasGradient | CanvasPattern
        {
            let s= this;
            let grd:any;
            let x:number,y:number;
            let i:number,len:number;
            let c:number,a:number,r:number;
            let rx:number,ry:number;
            if(s.$gradientType == GradientType.LINEAR.name)
            {   
                len = s.$color.length;
                x = s.width*s.$gradientMatrix.a + s.$gradientMatrix.tx;
                y = s.height*s.$gradientMatrix.b + s.$gradientMatrix.ty;
                grd = ctx.createLinearGradient(0,0,x,y);                
                for(i=0;i<len;++i)
                {
                    a = a > 1?a:(s.$alpha[i]?s.$alpha[i]:1)*255|0;
                    c = s.$color[i];   
                    r = s.$ratio[i]>1?s.$ratio[i]/255|0:(i<s.$ratio.length?s.$ratio[i]:1);
                    grd.addColorStop(r,egret.toColorString(c) + a.toString(16));                    
                }
            }
            else if(s.$gradientType == GradientType.RADIAL.name)
            {
                len = s.$color.length;
                rx = s.width >> 1;
                ry = s.height >> 1;
                x = rx*s.$gradientMatrix.a + ry*s.$gradientMatrix.c + s.$gradientMatrix.tx;
                y = rx*s.$gradientMatrix.b + ry*s.$gradientMatrix.d + s.$gradientMatrix.ty;
                grd = ctx.createRadialGradient(x,y,1,x,y,rx);                
                for(i=0;i<len;++i)
                {
                    a = (s.$alpha[i]?s.$alpha[i]:1)*255|0;
                    c = s.$color[i];   
                    r = s.$ratio[i]>1?s.$ratio[i]/255|0:(i<s.$ratio.length?s.$ratio[i]:1);
                    grd.addColorStop(r,egret.toColorString(c) + a.toString(16));
                }
            }
            else
            {
                return s.$color.length > 0?egret.toColorString(s.$color[0]):null;
            }
            return grd;
        }
        /**笔触的颜色、渐变或模式*/
        public getStrokeStyle(ctx:CanvasRenderingContext2D):string | CanvasGradient | CanvasPattern
        {
            let s= this;
            let grd:any;
            let x:number,y:number;
            let i:number,len:number;
            let c:number,a:number,r:number;
            let rx:number,ry:number;
            if(s.$gradientType == GradientType.LINEAR.name)
            {   
                len = s.$color.length;
                x = s.width*s.$gradientMatrix.a + s.$gradientMatrix.tx;
                y = s.height*s.$gradientMatrix.b + s.$gradientMatrix.ty;
                grd = ctx.createLinearGradient(0,0,x,y);                
                for(i=0;i<len;++i)
                {
                    a = (s.$alpha[i]?s.$alpha[i]:1)*255|0;
                    c = s.$color[i];   
                    r = s.$ratio[i]>1?s.$ratio[i]/255|0:(i<s.$ratio.length?s.$ratio[i]:1);
                    grd.addColorStop(r,egret.toColorString(c) + a.toString(16));
                }
            }
            else if(s.$gradientType == GradientType.RADIAL.name)
            {
                len = s.$color.length;
                rx = s.width >> 1;
                ry = s.height >> 1;
                x = rx*s.$gradientMatrix.a + ry*s.$gradientMatrix.c + s.$gradientMatrix.tx;
                y = rx*s.$gradientMatrix.b + ry*s.$gradientMatrix.d + s.$gradientMatrix.ty;
                grd = ctx.createRadialGradient(x,y,1,x,y,rx);                
                for(i=0;i<len;++i)
                {
                    a = (s.$alpha[i]?s.$alpha[i]:1)*255|0;
                    c = s.$color[i];   
                    r = s.$ratio[i]>1?s.$ratio[i]/255|0:(i<s.$ratio.length?s.$ratio[i]:1);
                    grd.addColorStop(r,egret.toColorString(c) + a.toString(16));
                }
            }
            else
            {
                return s.$color.length > 0?egret.toColorString(s.$color[0]):null;
            }
            return grd;
        }
        public get blurSizeY():number
        {
            return this.$blurSize;
        }
        public get blurSizeX():number
        {            
            return this.$type == GraphicsType.LINE?0:this.$blurSize;
        }
        /**设置圆角*/
        private setRoundRectRadius(rx:number,ry:number):void
        {
            let s= this;
            s.$rectRadiusX = rx > 0?rx:5;
            s.$rectRadiusY = ry > 0?ry:rx;
            s.$lineRect.leftGap = s.$lineRect.rightGap = s.$rectRadiusX + 1 + s.$gap;
            s.$lineRect.topGap = s.$lineRect.bottomGap = s.$rectRadiusY + 1 + s.$gap;
            s.$scaleSizeX = 2;
            s.$scaleSizeY = 2;
            s.width = s.$scaleSizeX + s.$lineRect.leftGap*2;
            s.height = s.$scaleSizeY + s.$lineRect.topGap*2;
        }
        
        
        public getScaleRect(type:GraphicsType=null,thickness:number=1):GYLite.Scale9GridRect
        {let s= this;
            if(type == null || type == GraphicsType.LINE)
            {                
                return s.$lineRect;                
            }
            else
            {
                return s.$lineRect;
            }
        }
    }    
}